﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Vds2465Telegrams;

namespace Vds2465Parser
{
	[TestClass]
	public class Generator_FixedLength_Test
	{
		#region constants

		private const int fixedLengthTelegrams_Length = 5;
		private const byte fixedLengthTelegrams_FirstByteValue = 0x10;
		private const byte fixedLengthTelegrams_LastByteValue = 0x16;

		#endregion constants

		#region tests

		#region calling telegram tests

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test01_SEND_NORM()
		{
            // first generate bytes
			Telegram_Calling telegramCalling = new Telegram_Calling(eDirection.ATE_to_RCT, 0x57, eTelegramFunction_Calling.SEND_NORM, false, true);

            IGeneratorParser generatorParser = GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegramCalling);
			// 0x10, 0xe0, 0x57, 0x37, 0x16
			AssertFixedLengthTelegram(0xe0, telegramCalling.Address, telegramBytes);	
		
            // second parse the generated bytes
            Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
            Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegramCalling.Equals(telegramParsed));
		}
		
		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test02_REQ_STATUS()
		{
			Telegram_Calling telegramCalling = new Telegram_Calling(eDirection.ATE_to_RCT, 0x66, eTelegramFunction_Calling.REQ_STATUS, true, true);
            IGeneratorParser generatorParser = GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegramCalling);
			// 0x10, 0xF9, 0x66, 0x5F, 0x16
			AssertFixedLengthTelegram(0xF9, telegramCalling.Address, telegramBytes);

            // second parse the generated bytes
            Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
            Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegramCalling.Equals(telegramParsed));
		}

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test03_REQ_NDAT()
		{
			Telegram_Calling telegramCalling = new Telegram_Calling(eDirection.ATE_to_RCT, 0x66, eTelegramFunction_Calling.REQ_NDAT, true, false);
            IGeneratorParser generatorParser = GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegramCalling);
			// 0x10, 0xDA, 0x66, 0x40, 0x16
			AssertFixedLengthTelegram(0xDA, telegramCalling.Address, telegramBytes);

            // second parse the generated bytes
            Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
            Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegramCalling.Equals(telegramParsed));
		}

		#endregion calling telegram tests

		#region returning telegram tests

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test10__CONFIRM_ACK()
		{
			// TODO: Variable Length?
		}

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test11__CONFIRM_NAK()
		{
			Telegram_Returning telegramReturning = new Telegram_Returning(eDirection.ATE_to_RCT, 0x77, eTelegramFunction_Returning.CONFIRM_NAK, true, true);

            IGeneratorParser generatorParser = GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegramReturning);
			// 0x10, 0xB1, 0x77, 0x28, 0x16
			AssertFixedLengthTelegram(0xB1, telegramReturning.Address, telegramBytes);

            // second parse the generated bytes
            Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
            Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegramReturning.Equals(telegramParsed));
		}

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test12_FC_ERROR()
		{
			Telegram_Returning telegramReturning = new Telegram_Returning(eDirection.ATE_to_RCT, 0x77, eTelegramFunction_Returning.FC_ERROR, false, false);

            IGeneratorParser generatorParser = GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegramReturning);
			// 0x10, 0x86, 0x77, 0xFD, 0x16
			AssertFixedLengthTelegram(0x86, telegramReturning.Address, telegramBytes);

            // second parse the generated bytes
            Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
            Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegramReturning.Equals(telegramParsed));
		}

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test13_RESPOND_NDAT()
		{
			// TODO: Variable Length
		}

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test14_RESPOND_NAK()
		{
			Telegram_Returning telegramReturning = new Telegram_Returning(eDirection.RCT_to_ACE, 0xFF, eTelegramFunction_Returning.RESPOND_NAK, false, true);

            IGeneratorParser generatorParser = GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegramReturning);
			// 0x10, 0x19, 0xFF, 0x18, 0x16
			AssertFixedLengthTelegram(0x19, telegramReturning.Address, telegramBytes);

            // second parse the generated bytes
            Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
            Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegramReturning.Equals(telegramParsed));
		}

		[TestMethod]
		[Owner("Frank Eppink")]
		public void Test15_RESPOND_STATUS()
		{
			Telegram_Returning telegramReturning = new Telegram_Returning(eDirection.RCT_to_ACE, 0x01, eTelegramFunction_Returning.RESPOND_STATUS, true, false);
            IGeneratorParser generatorParser = GetGeneratorParser();
			byte[] telegramBytes = generatorParser.GenerateTelegramBytes(telegramReturning);
			// 0x10, 0x2B, 0x01, 0x2C, 0x16
			AssertFixedLengthTelegram(0x2B, telegramReturning.Address, telegramBytes);

            // second parse the generated bytes
            Telegram telegramParsed = generatorParser.ParseTelegramBytes(telegramBytes);
            Assert.IsNotNull(telegramParsed);
			Assert.IsTrue(telegramReturning.Equals(telegramParsed));
		}

		#endregion returning telegram tests

		#endregion tests

		#region helper methods

        private IGeneratorParser GetGeneratorParser()
        {
            return new GeneratorParser();
        }

		private void AssertFixedLengthTelegram(byte expectedControlByte, byte expectedAddressByte, byte[] fixedLengthTelegramBytes2Check)
		{
			Assert.IsNotNull(fixedLengthTelegramBytes2Check);
			
			Assert.AreEqual(fixedLengthTelegrams_Length, fixedLengthTelegramBytes2Check.Length);
			
			Assert.AreEqual(fixedLengthTelegrams_FirstByteValue, fixedLengthTelegramBytes2Check[0]);
						
			Assert.AreEqual(expectedControlByte, fixedLengthTelegramBytes2Check[1]);

			Assert.AreEqual(expectedAddressByte, fixedLengthTelegramBytes2Check[2]);

			byte expectedChecksumValue = (byte) (fixedLengthTelegramBytes2Check[1] + fixedLengthTelegramBytes2Check[2]);
			Assert.AreEqual(expectedChecksumValue, fixedLengthTelegramBytes2Check[3]);
						
			Assert.AreEqual(fixedLengthTelegrams_LastByteValue, fixedLengthTelegramBytes2Check[4]);
		}

		#endregion helper methods
	}
}
